from PyQt5.Qsci import QsciScintilla, QsciLexerPython, QsciScintillaBase
from PyQt5.QtGui import QFont, QColor

"""
编辑器相关配置，目前使用QsciScintilla实现编辑器
"""


class IEditor(object):
    def config(self):
        pass


class QScintillaCodeEditor(IEditor):

    def __init__(self, editor: QsciScintilla):
        self.editor = editor
        self.lexer = QsciLexerPython(self.editor)
        self.editor.setLexer(self.lexer)

    def config(self):
        """
        配置编辑器
        """
        self._code_style()
        self._settings()

    def _code_style(self):
        # 代码字体字号
        self.lexer.setFont(QFont("Monaco", 14))
        # self.lexer.setFont(QFont("Consolas", 14), QsciLexerPython.Comment)

        # 字体背景颜色和前景颜色
        self.editor.SendScintilla(self.editor.SCI_STYLESETBACK, 0, QColor(30, 30, 30).rgb())  # 背景色
        self.editor.SendScintilla(self.editor.SCI_STYLESETFORE, 0, QColor(255, 255, 255).rgb())  # 默认前景色

        # 语法元素颜色
        self.lexer.setColor(QColor(0, 255, 0), QsciLexerPython.Keyword)  # 关键字：绿色
        self.lexer.setColor(QColor(255, 255, 0), QsciLexerPython.Comment)  # 注释：黄色
        self.lexer.setColor(QColor(255, 165, 0), QsciLexerPython.Number)  # 数字：橙色

        # 选中行高亮、高亮色
        self.editor.setCaretLineVisible(True)
        self.editor.setCaretLineBackgroundColor(QColor(221, 216, 215, 100))

        # 设置行号
        # editor设置页边特性。 这里有3种Margin：[0]行号 [1]改动标识 [2]代码折叠
        # self.editor.setMarginLineNumbers(1, True)  # 设置标号为0的页边显示行号
        self.editor.setMarginWidth(0, '000')  # 行号宽度
        # self.editor.setMarkerForegroundColor(QColor("#FFFFFF"), 0)
        # 设置改动标记
        # self.editor.setMarginType(1, QsciScintilla.SymbolMargin)  # 设置标号为1的页边用于显示改动标记
        self.editor.setMarginsBackgroundColor(QColor(106, 106, 106))  # 边栏背景色
        self.editor.setMarginsForegroundColor(QColor(200, 200, 200))  # 边栏行号字色

    def _settings(self):
        # 文件中的每一行都以EOL字符结尾（换行符为 \r \n）
        self.editor.setEolMode(QsciScintilla.EolUnix)
        self.editor.setAutoIndent(True)  # 换行后自动缩进
        self.editor.setUtf8(True)  # 支持中文字符

        # 设置 Tab 键功能
        self.editor.setIndentationsUseTabs(True)  # 行首缩进采用Tab键，反向缩进是Shift +Tab
        self.editor.setIndentationWidth(4)  # 行首缩进宽度为4个空格
        self.editor.setIndentationGuides(True)  # 显示虚线垂直线的方式来指示缩进
        self.editor.setTabIndents(True)  # 编辑器将行首第一个非空格字符推送到下一个缩进级别
        self.editor.setAutoIndent(True)  # 插入新行时，自动缩进将光标推送到与前一个相同的缩进级别
        self.editor.setTabWidth(4)  # Tab 等于 4 个空格

        # 其它配置项
        self.editor.setEolMode(QsciScintillaBase.SC_EOL_LF)  # 以\n换行
        self.editor.setWrapMode(QsciScintillaBase.SC_WRAP_WORD)  # 自动换行
        self.editor.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll)  # 自动补全。对于所有Ascii字符
        self.editor.setAutoCompletionCaseSensitivity(False)  # 自动补全大小写敏感
        self.editor.setAutoCompletionThreshold(1)  # 输入多少个字符才弹出补全提示
        # self.editor.setFolding(True)  # 代码可折叠
        self.editor.setAutoIndent(True)  # 换行后自动缩进


class QScintillaLogEditor(IEditor):
    def __init__(self, editor: QsciScintilla):
        self.editor = editor

    def config(self):
        self.editor.setReadOnly(True)
        self.editor.setMarginWidth(2, '000')
        self.editor.setFont(QFont("Consolas", 12))
        self.editor.setMarginsBackgroundColor(QColor(106, 106, 106))  # 边栏背景颜色
